<template>
  <div class="power-load-dashboard">
    <div class="header">
      <h1>电力负荷数据可视化分析</h1>
      <div class="upload-section">
        <input type="file" @change="handleFileUpload" accept=".csv" ref="fileInput" class="file-input">
        <button @click="$refs.fileInput.click()" class="upload-btn">
          上传CSV文件
        </button>
      </div>
    </div>

    <div v-if="data.length > 0" class="dashboard-content">
      <!-- 数据概览 -->
      <div class="stats-grid">
        <div class="stat-card">
          <h3>总数据量</h3>
          <p>{{ data.length.toLocaleString() }}</p>
        </div>
        <div class="stat-card">
          <h3>平均负荷</h3>
          <p>{{ averageLoad.toFixed(2) }} kW</p>
        </div>
        <div class="stat-card">
          <h3>最大负荷</h3>
          <p>{{ maxLoad.toFixed(2) }} kW</p>
        </div>
        <div class="stat-card">
          <h3>最小负荷</h3>
          <p>{{ minLoad.toFixed(2) }} kW</p>
        </div>
      </div>

      <!-- 图表控制 -->
      <div class="controls">
        <div class="control-group">
          <label>图表类型:</label>
          <select v-model="chartType" @change="updateChart">
            <option value="line">时序折线图</option>
            <option value="scatter">温度-负荷散点图</option>
            <option value="bar">小时负荷柱状图</option>
            <option value="heatmap">负荷热力图</option>
          </select>
        </div>

        <div class="control-group">
          <label>数据范围:</label>
          <select v-model="dataRange" @change="updateChart">
            <option value="100">前100条</option>
            <option value="500">前500条</option>
            <option value="1000">前1000条</option>
            <option value="all">全部数据</option>
          </select>
        </div>
      </div>

      <!-- 图表区域 -->
      <div class="chart-container">
        <canvas ref="chart" width="800" height="400"></canvas>
      </div>

      <!-- 相关性分析 -->
      <div class="analysis-section">
        <h3>相关性分析</h3>
        <div class="correlation-grid">
          <div class="correlation-item">
            <span>负荷与温度相关性:</span>
            <span class="correlation-value">{{ correlations.temperature }}</span>
          </div>
          <div class="correlation-item">
            <span>负荷与湿度相关性:</span>
            <span class="correlation-value">{{ correlations.humidity }}</span>
          </div>
          <div class="correlation-item">
            <span>负荷与风速相关性:</span>
            <span class="correlation-value">{{ correlations.windSpeed }}</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import Chart from 'chart.js/auto'

export default {
  name: 'PowerLoadVisualization',
  data() {
    return {
      data: [],
      chart: null,
      chartType: 'line',
      dataRange: '500',
      fileContent: null
    }
  },
  computed: {
    averageLoad() {
      if (this.data.length === 0) return 0
      return this.data.reduce((sum, item) => sum + parseFloat(item.value), 0) / this.data.length
    },
    maxLoad() {
      if (this.data.length === 0) return 0
      return Math.max(...this.data.map(item => parseFloat(item.value)))
    },
    minLoad() {
      if (this.data.length === 0) return 0
      return Math.min(...this.data.map(item => parseFloat(item.value)))
    },
    correlations() {
      if (this.data.length === 0) return { temperature: 0, humidity: 0, windSpeed: 0 }

      const values = this.data.map(item => parseFloat(item.value))
      const temperatures = this.data.map(item => parseFloat(item.temperature))
      const humidity = this.data.map(item => parseFloat(item.humidity))
      const windSpeed = this.data.map(item => parseFloat(item.wind_speed))

      return {
        temperature: this.calculateCorrelation(values, temperatures).toFixed(3),
        humidity: this.calculateCorrelation(values, humidity).toFixed(3),
        windSpeed: this.calculateCorrelation(values, windSpeed).toFixed(3)
      }
    },
    filteredData() {
      if (this.dataRange === 'all') return this.data
      return this.data.slice(0, parseInt(this.dataRange))
    }
  },
  methods: {
    async handleFileUpload(event) {
      const file = event.target.files[0]
      if (!file) return

      const text = await file.text()
      this.parseCSV(text)
    },

    parseCSV(text) {
      const lines = text.trim().split('\n')
      const headers = lines[0].split(',')
      const data = []

      for (let i = 1; i < lines.length; i++) {
        const values = lines[i].split(',')
        const row = {}
        headers.forEach((header, index) => {
          row[header.trim()] = values[index]?.trim() || ''
        })
        data.push(row)
      }

      this.data = data
      this.$nextTick(() => {
        this.updateChart()
      })
    },

    updateChart() {
      if (this.chart) {
        this.chart.destroy()
      }

      const ctx = this.$refs.chart.getContext('2d')

      switch (this.chartType) {
        case 'line':
          this.createLineChart(ctx)
          break
        case 'scatter':
          this.createScatterChart(ctx)
          break
        case 'bar':
          this.createBarChart(ctx)
          break
        case 'heatmap':
          this.createHeatmapChart(ctx)
          break
      }
    },

    createLineChart(ctx) {
      const data = this.filteredData
      const labels = data.map((_, index) => `${Math.floor(index / 4)}:${(index % 4) * 15}`)
      const values = data.map(item => parseFloat(item.value))

      this.chart = new Chart(ctx, {
        type: 'line',
        data: {
          labels: labels,
          datasets: [{
            label: '电力负荷 (kW)',
            data: values,
            borderColor: '#3498db',
            backgroundColor: 'rgba(52, 152, 219, 0.1)',
            tension: 0.4,
            fill: true
          }]
        },
        options: {
          responsive: true,
          plugins: {
            title: {
              display: true,
              text: '电力负荷时序变化'
            }
          },
          scales: {
            y: {
              beginAtZero: false,
              title: {
                display: true,
                text: '负荷 (kW)'
              }
            },
            x: {
              title: {
                display: true,
                text: '时间'
              }
            }
          }
        }
      })
    },

    createScatterChart(ctx) {
      const data = this.filteredData
      const scatterData = data.map(item => ({
        x: parseFloat(item.temperature),
        y: parseFloat(item.value)
      }))

      this.chart = new Chart(ctx, {
        type: 'scatter',
        data: {
          datasets: [{
            label: '负荷 vs 温度',
            data: scatterData,
            backgroundColor: 'rgba(231, 76, 60, 0.6)',
            borderColor: '#e74c3c'
          }]
        },
        options: {
          responsive: true,
          plugins: {
            title: {
              display: true,
              text: '负荷与温度关系散点图'
            }
          },
          scales: {
            x: {
              title: {
                display: true,
                text: '温度 (°C)'
              }
            },
            y: {
              title: {
                display: true,
                text: '负荷 (kW)'
              }
            }
          }
        }
      })
    },

    createBarChart(ctx) {
      const data = this.filteredData
      const hourlyData = {}

      data.forEach(item => {
        const hour = Math.floor(parseFloat(item.minute) / 60)
        if (!hourlyData[hour]) {
          hourlyData[hour] = { sum: 0, count: 0 }
        }
        hourlyData[hour].sum += parseFloat(item.value)
        hourlyData[hour].count++
      })

      const hours = Object.keys(hourlyData).sort((a, b) => parseInt(a) - parseInt(b))
      const avgLoads = hours.map(hour => hourlyData[hour].sum / hourlyData[hour].count)

      this.chart = new Chart(ctx, {
        type: 'bar',
        data: {
          labels: hours.map(h => `${h}:00`),
          datasets: [{
            label: '平均负荷 (kW)',
            data: avgLoads,
            backgroundColor: 'rgba(46, 204, 113, 0.7)',
            borderColor: '#2ecc71',
            borderWidth: 1
          }]
        },
        options: {
          responsive: true,
          plugins: {
            title: {
              display: true,
              text: '小时平均负荷分布'
            }
          },
          scales: {
            y: {
              beginAtZero: false,
              title: {
                display: true,
                text: '负荷 (kW)'
              }
            },
            x: {
              title: {
                display: true,
                text: '小时'
              }
            }
          }
        }
      })
    },

    createHeatmapChart(ctx) {
      // 简化版热力图实现
      const data = this.filteredData.slice(0, 168) // 一周的数据
      const values = data.map(item => parseFloat(item.value))
      const normalizedValues = this.normalizeArray(values)

      // 创建颜色映射的柱状图来模拟热力图
      this.chart = new Chart(ctx, {
        type: 'bar',
        data: {
          labels: data.map((_, index) => `${Math.floor(index / 24)}天${index % 24}时`),
          datasets: [{
            label: '负荷热力图',
            data: values,
            backgroundColor: normalizedValues.map(val =>
              `rgba(${Math.floor(255 * val)}, ${Math.floor(100 * (1 - val))}, ${Math.floor(50 * (1 - val))}, 0.8)`
            ),
            borderWidth: 0
          }]
        },
        options: {
          responsive: true,
          plugins: {
            title: {
              display: true,
              text: '负荷热力图 (颜色深度表示负荷大小)'
            }
          },
          scales: {
            y: {
              title: {
                display: true,
                text: '负荷 (kW)'
              }
            }
          }
        }
      })
    },

    calculateCorrelation(x, y) {
      const n = x.length
      const sumX = x.reduce((a, b) => a + b, 0)
      const sumY = y.reduce((a, b) => a + b, 0)
      const sumXY = x.reduce((sum, xi, i) => sum + xi * y[i], 0)
      const sumX2 = x.reduce((sum, xi) => sum + xi * xi, 0)
      const sumY2 = y.reduce((sum, yi) => sum + yi * yi, 0)

      const numerator = n * sumXY - sumX * sumY
      const denominator = Math.sqrt((n * sumX2 - sumX * sumX) * (n * sumY2 - sumY * sumY))

      return denominator === 0 ? 0 : numerator / denominator
    },

    normalizeArray(arr) {
      const min = Math.min(...arr)
      const max = Math.max(...arr)
      return arr.map(val => (val - min) / (max - min))
    }
  }
}
</script>

<style scoped>
.power-load-dashboard {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
  font-family: 'Arial', sans-serif;
}

.header {
  text-align: center;
  margin-bottom: 30px;
}

.header h1 {
  color: #2c3e50;
  margin-bottom: 20px;
  font-size: 2.5em;
}

.upload-section {
  margin-bottom: 30px;
}

.file-input {
  display: none;
}

.upload-btn {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border: none;
  padding: 12px 24px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 16px;
  transition: transform 0.2s;
}

.upload-btn:hover {
  transform: translateY(-2px);
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
  margin-bottom: 30px;
}

.stat-card {
  background: white;
  padding: 20px;
  border-radius: 10px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  text-align: center;
}

.stat-card h3 {
  color: #7f8c8d;
  margin-bottom: 10px;
  font-size: 14px;
}

.stat-card p {
  color: #2c3e50;
  font-size: 24px;
  font-weight: bold;
}

.controls {
  display: flex;
  gap: 20px;
  margin-bottom: 30px;
  justify-content: center;
}

.control-group {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.control-group label {
  font-weight: bold;
  color: #2c3e50;
}

.control-group select {
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
}

.chart-container {
  background: white;
  padding: 20px;
  border-radius: 10px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  margin-bottom: 30px;
}

.analysis-section {
  background: white;
  padding: 20px;
  border-radius: 10px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.analysis-section h3 {
  color: #2c3e50;
  margin-bottom: 15px;
}

.correlation-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 15px;
}

.correlation-item {
  display: flex;
  justify-content: space-between;
  padding: 10px;
  background: #f8f9fa;
  border-radius: 5px;
}

.correlation-value {
  font-weight: bold;
  color: #3498db;
}

@media (max-width: 768px) {
  .controls {
    flex-direction: column;
    align-items: center;
  }

  .stats-grid {
    grid-template-columns: 1fr;
  }
}
</style>